using System;
using System.DirectoryServices;
using System.Text;
using ActiveDs;
using System.Diagnostics;
using System.Data;
using System.Web.Mail;
using System.Configuration;
using System.IO;
using System.Windows.Forms;
namespace AccountMailer.NET
{
	/// <summary>
	/// Summary description for DirectoryLookup.
	/// </summary>
		

	public class DirectoryLookup
	{
		public DataSet dstResults = new DataSet("dstResults");
		public bool debug ;
		public DirectoryLookup()
		{
			if (ConfigurationSettings.AppSettings["debug"].ToString().ToLower() =="true") debug=true; else debug=false;

		}

		public void ErrorReport(Exception errReport)
		{
			
			string ErrorMessage = errReport.Message + "\r\n" + errReport.Source + "\r\n" + errReport.StackTrace.ToString();
			Console.WriteLine (ErrorMessage);
			EventLog.WriteEntry ("AccountMailer", ErrorMessage , System.Diagnostics.EventLogEntryType.Error);

		}
		public bool PerformSearch(int intDateBeforeExpiration, string Domain)
		{
			bool success = true;
			DataTable tblResults = new DataTable("Results");
			dstResults.Tables.Add (tblResults);
			tblResults.Columns.Add ("UserName");tblResults.Columns.Add("DaysBeforeExpiration");tblResults.Columns.Add ("email");
			tblResults.Columns.Add ("LastName"); tblResults.Columns.Add ("FirstName");
			Console.WriteLine ("Searching accounts in domain: " + Domain);
			DirectoryEntry dirEntry = new DirectoryEntry ("LDAP://" + Domain);
			DirectorySearcher dirSearcher = new DirectorySearcher (dirEntry);
			LargeInteger lMaxPasswordAge =  dirEntry.Properties["maxPwdAge"].Value as LargeInteger ;
			dirSearcher.Filter = "(&(objectCategory=person)(samAccountName=*))";
			dirSearcher.Sort = new System.DirectoryServices.SortOption("samAccountName", SortDirection.Ascending);

			long datMaxPasswordAge = (((long)(lMaxPasswordAge.HighPart) << 32) + (long) lMaxPasswordAge.LowPart);
			TimeSpan maxPwd = new TimeSpan(datMaxPasswordAge);
			dirSearcher.PageSize=500;
			foreach (SearchResult dirResult in dirSearcher.FindAll())
			{
				try
				{
					DirectoryEntry dirUser = new DirectoryEntry (dirResult.Path);
					if (debug==true) Console.WriteLine(dirUser.Path.ToString());
					//dirEntry.NativeObject.PasswordLastChanged;
					//System.Int64 int64pwdLastSet =  dirResult.Properties["pwdlastset"];
					LargeInteger  lPasswordLastSet= dirUser.Properties["pwdlastset"].Value as LargeInteger ;
					long datPasswordLastSet = (((long)(lPasswordLastSet.HighPart) << 32) + (long) lPasswordLastSet.LowPart);
					DateTime datPasswordExpires = DateTime.FromFileTime(datPasswordLastSet).Subtract(maxPwd);
					TimeSpan datBeforExpiration = datPasswordExpires.Subtract(DateTime.Now);
					bool blnBreak;
					
					string samAccountName = dirUser.Properties["samAccountName"].Value.ToString();
					blnBreak = (samAccountName.IndexOf("gsu")>=0);

					if (debug==true) Console.WriteLine(samAccountName);
					if (datBeforExpiration.Days<intDateBeforeExpiration && datBeforExpiration.Days>=0 && samAccountName[samAccountName.Length -1].ToString()!="$" && dirUser.Properties["mail"].Value!=null && !samAccountName.StartsWith("svcacct") && ((int)dirUser.Properties["userAccountControl"].Value & 0x10000)==0)
					{

						//string datA = datTotal.ToString();
						if (debug==true) Console.WriteLine("getting email ...");
						string emailAddr = dirUser.Properties["mail"].Value.ToString();
						if (debug==true) Console.WriteLine(emailAddr);
						//Console.WriteLine (dirResult.GetDirectoryEntry().Properties
						Debug.WriteLine (dirUser.Properties["samAccountName"].Value.ToString() + ":" + emailAddr + ":" + datBeforExpiration.Days.ToString());
						DataRow dr= tblResults.NewRow();
						dr["UserName"] = samAccountName;
						dr["LastName"]=((dirUser.Properties["sn"].Value==null) ? "No Last Name" :  dirUser.Properties["sn"].Value.ToString ());
						//dr["LastName"] = dirUser.Properties["sn"].Value.ToString ();
						dr["FirstName"] = ((dirUser.Properties["givenName"].Value==null)?  "No First Name":dirUser.Properties["givenName"].Value.ToString());
						dr["email"] = emailAddr;

						dr["DaysBeforeExpiration"]= datBeforExpiration.Days;
						tblResults.Rows.Add(dr);
						Console.WriteLine (samAccountName + " : " + emailAddr + " : " + datBeforExpiration.Days.ToString());
					}
				}
				catch (Exception e)
				{
					ErrorReport(e);
					success = false;
				}
			}
			Console.WriteLine  ("Number of accounts found : " + tblResults.Rows.Count.ToString());

			
			return success;									 					 
		}
		public bool SendEmail()
		{
			bool success= true;
			try
			{
					string strTemplate = "";
				using (StreamReader sr = new StreamReader (Application.StartupPath.ToString() + "\\mail.html"))
				{

					string line;
					while ((line = sr.ReadLine()) != null) 
					{
						strTemplate= strTemplate + line;
					}
				}
				if (debug==true) Console.WriteLine ("Debug mode is set to TRUE, so sending emails to"  +  ConfigurationSettings.AppSettings["debug email"].ToString());
				foreach (DataRow  objRow in dstResults.Tables["results"].Rows)
				{
					String tempString = strTemplate;
					tempString = tempString.Replace ("$FirstName", objRow ["FirstName"].ToString());
					tempString = tempString.Replace ("$LastName", objRow ["LastName"].ToString ());
					tempString = tempString.Replace ("$DaysBeforeExpiration", objRow ["DaysBeforeExpiration"].ToString ());					
					tempString = tempString.Replace ("$domain", ConfigurationSettings.AppSettings["domain"].ToString());
					MailMessage msgEmail = new MailMessage();
					msgEmail.From = ConfigurationSettings.AppSettings["fromEmail"].ToString();
					if (debug==true)
					{
						msgEmail.To = ConfigurationSettings.AppSettings["debug email"].ToString();}

					else 
					{
						msgEmail.To = objRow ["email"].ToString();
						Console.WriteLine ("Debug mode is FALSE, so sending emails to actual recepients");
					}
					msgEmail.BodyFormat = MailFormat.Html;
					msgEmail.Body = tempString;
					msgEmail.Priority = MailPriority.High;
					msgEmail.Subject = ConfigurationSettings.AppSettings["subject"].ToString();
					SmtpMail.SmtpServer = ConfigurationSettings.AppSettings["relay server"].ToString();
					Console.WriteLine ("Email Sent to: " + objRow["email"].ToString());
					SmtpMail.Send(msgEmail);

				}
			}
			catch (Exception e)
			{
				ErrorReport(e);
				success = false;
			}
			Console.WriteLine ("Writing results file to " + Application.StartupPath.ToString());
			dstResults.WriteXml (Application.StartupPath.ToString()  + "\\" + String.Format  ("{0:D} {0:hh.mm.ss} {0:ffff}", DateTime.Now) + ".xml");
			return success;
		}
	}
}
